﻿using System;
using System.Linq;
using TSharp.Core.Osgi;
using TSharp.Core;

namespace TSharp.Core.Repository
{
    /// <summary>
    /// Base class for <see cref="IQueryable"/> based specifications.
    /// </summary>
    public abstract class QueryableSpecification<TEntity> : ISpecification<TEntity>
        where TEntity : class
    {
        /// <summary>
        /// Constructor.
        /// </summary>
        public QueryableSpecification()
        {
            this.UnitOfWorkConvertor = AopContext.GetDefaultLactor().Get<IUnitOfWorkConvertor>();
        }

        /// <summary>
        /// Gets or sets the queryable instance.
        /// </summary>
        public IQueryable<TEntity> Queryable { get; private set; }

        /// <summary>
        /// Gets unit of work convertor.
        /// </summary>
        protected IUnitOfWorkConvertor UnitOfWorkConvertor { get; private set; }

        /// <summary>
        /// Initializes specification from given unit of work.
        /// Implementation varies on <see cref="IUnitOfWork"/> implementation.
        /// </summary>
        public virtual void Initialize(IUnitOfWork unitOfWork)
        {
            this.Queryable = this.UnitOfWorkConvertor.ToQueryable<TEntity>(unitOfWork);
        }

        /// <summary>
        /// Returns queryable specification result.
        /// </summary>
        public ISpecificationResult<TEntity> ToResult()
        {
            return new QueryableSpecificationResult<TEntity>(Queryable);
        }



    }
}
